//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension DocDBElastic {
    // MARK: Enums

    public enum Auth: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case plainText = "PLAIN_TEXT"
        case secretArn = "SECRET_ARN"
        public var description: String { return self.rawValue }
    }

    public enum OptInType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case applyOn = "APPLY_ON"
        case immediate = "IMMEDIATE"
        case nextMaintenance = "NEXT_MAINTENANCE"
        case undoOptIn = "UNDO_OPT_IN"
        public var description: String { return self.rawValue }
    }

    public enum SnapshotType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case automated = "AUTOMATED"
        case manual = "MANUAL"
        public var description: String { return self.rawValue }
    }

    public enum Status: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case active = "ACTIVE"
        case copying = "COPYING"
        case creating = "CREATING"
        case deleting = "DELETING"
        case inaccessibleEncryptionCredentialsRecoverable = "INACCESSIBLE_ENCRYPTION_CREDENTIALS_RECOVERABLE"
        case inaccessibleEncryptionCreds = "INACCESSIBLE_ENCRYPTION_CREDS"
        case inaccessibleSecretArn = "INACCESSIBLE_SECRET_ARN"
        case inaccessibleVpcEndpoint = "INACCESSIBLE_VPC_ENDPOINT"
        case incompatibleNetwork = "INCOMPATIBLE_NETWORK"
        case invalidSecurityGroupId = "INVALID_SECURITY_GROUP_ID"
        case invalidSubnetId = "INVALID_SUBNET_ID"
        case ipAddressLimitExceeded = "IP_ADDRESS_LIMIT_EXCEEDED"
        case maintenance = "MAINTENANCE"
        case merging = "MERGING"
        case modifying = "MODIFYING"
        case splitting = "SPLITTING"
        case starting = "STARTING"
        case stopped = "STOPPED"
        case stopping = "STOPPING"
        case updating = "UPDATING"
        case vpcEndpointLimitExceeded = "VPC_ENDPOINT_LIMIT_EXCEEDED"
        public var description: String { return self.rawValue }
    }

    public enum ValidationExceptionReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cannotParse = "cannotParse"
        case fieldValidationFailed = "fieldValidationFailed"
        case other = "other"
        case unknownOperation = "unknownOperation"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct ApplyPendingMaintenanceActionInput: AWSEncodableShape {
        /// The pending maintenance action to apply to the resource. Valid actions are:    ENGINE_UPDATE      ENGINE_UPGRADE     SECURITY_UPDATE     OS_UPDATE     MASTER_USER_PASSWORD_UPDATE
        public let applyAction: String
        /// A specific date to apply the pending maintenance action. Required if opt-in-type is APPLY_ON. Format: yyyy/MM/dd HH:mm-yyyy/MM/dd HH:mm
        public let applyOn: String?
        /// A value that specifies the type of opt-in request, or undoes an opt-in request. An opt-in request of type IMMEDIATE can't be undone.
        public let optInType: OptInType
        /// The Amazon DocumentDB Amazon Resource Name (ARN) of the resource to which the pending maintenance action applies.
        public let resourceArn: String

        @inlinable
        public init(applyAction: String, applyOn: String? = nil, optInType: OptInType, resourceArn: String) {
            self.applyAction = applyAction
            self.applyOn = applyOn
            self.optInType = optInType
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.applyAction, name: "applyAction", parent: name, max: 256)
            try self.validate(self.applyAction, name: "applyAction", parent: name, min: 1)
            try self.validate(self.applyOn, name: "applyOn", parent: name, max: 256)
            try self.validate(self.applyOn, name: "applyOn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case applyAction = "applyAction"
            case applyOn = "applyOn"
            case optInType = "optInType"
            case resourceArn = "resourceArn"
        }
    }

    public struct ApplyPendingMaintenanceActionOutput: AWSDecodableShape {
        /// The output of the pending maintenance action being applied.
        public let resourcePendingMaintenanceAction: ResourcePendingMaintenanceAction

        @inlinable
        public init(resourcePendingMaintenanceAction: ResourcePendingMaintenanceAction) {
            self.resourcePendingMaintenanceAction = resourcePendingMaintenanceAction
        }

        private enum CodingKeys: String, CodingKey {
            case resourcePendingMaintenanceAction = "resourcePendingMaintenanceAction"
        }
    }

    public struct Cluster: AWSDecodableShape {
        /// The name of the elastic cluster administrator.
        public let adminUserName: String
        /// The authentication type for the elastic cluster.
        public let authType: Auth
        /// The number of days for which automatic snapshots are retained.
        public let backupRetentionPeriod: Int?
        /// The ARN identifier of the elastic cluster.
        public let clusterArn: String
        /// The URL used to connect to the elastic cluster.
        public let clusterEndpoint: String
        /// The name of the elastic cluster.
        public let clusterName: String
        /// The time when the elastic cluster was created in Universal Coordinated Time (UTC).
        public let createTime: String
        /// The KMS key identifier to use to encrypt the elastic cluster.
        public let kmsKeyId: String
        /// The daily time range during which automated backups are created if automated backups are enabled, as determined by backupRetentionPeriod.
        public let preferredBackupWindow: String?
        /// The weekly time range during which system maintenance can occur, in Universal Coordinated Time (UTC).  Format: ddd:hh24:mi-ddd:hh24:mi
        public let preferredMaintenanceWindow: String
        /// The number of vCPUs assigned to each elastic cluster shard. Maximum is 64.  Allowed values are 2, 4, 8, 16, 32, 64.
        public let shardCapacity: Int
        /// The number of shards assigned to the elastic cluster. Maximum is 32.
        public let shardCount: Int
        /// The number of replica instances applying to all shards in the cluster.  A shardInstanceCount value of 1 means there is one writer instance, and any additional instances are replicas that can be used for reads and to improve availability.
        public let shardInstanceCount: Int?
        /// The total number of shards in the cluster.
        public let shards: [Shard]?
        /// The status of the elastic cluster.
        public let status: Status
        /// The Amazon EC2 subnet IDs for the elastic cluster.
        public let subnetIds: [String]
        /// A list of EC2 VPC security groups associated with thie elastic cluster.
        public let vpcSecurityGroupIds: [String]

        @inlinable
        public init(adminUserName: String, authType: Auth, backupRetentionPeriod: Int? = nil, clusterArn: String, clusterEndpoint: String, clusterName: String, createTime: String, kmsKeyId: String, preferredBackupWindow: String? = nil, preferredMaintenanceWindow: String, shardCapacity: Int, shardCount: Int, shardInstanceCount: Int? = nil, shards: [Shard]? = nil, status: Status, subnetIds: [String], vpcSecurityGroupIds: [String]) {
            self.adminUserName = adminUserName
            self.authType = authType
            self.backupRetentionPeriod = backupRetentionPeriod
            self.clusterArn = clusterArn
            self.clusterEndpoint = clusterEndpoint
            self.clusterName = clusterName
            self.createTime = createTime
            self.kmsKeyId = kmsKeyId
            self.preferredBackupWindow = preferredBackupWindow
            self.preferredMaintenanceWindow = preferredMaintenanceWindow
            self.shardCapacity = shardCapacity
            self.shardCount = shardCount
            self.shardInstanceCount = shardInstanceCount
            self.shards = shards
            self.status = status
            self.subnetIds = subnetIds
            self.vpcSecurityGroupIds = vpcSecurityGroupIds
        }

        private enum CodingKeys: String, CodingKey {
            case adminUserName = "adminUserName"
            case authType = "authType"
            case backupRetentionPeriod = "backupRetentionPeriod"
            case clusterArn = "clusterArn"
            case clusterEndpoint = "clusterEndpoint"
            case clusterName = "clusterName"
            case createTime = "createTime"
            case kmsKeyId = "kmsKeyId"
            case preferredBackupWindow = "preferredBackupWindow"
            case preferredMaintenanceWindow = "preferredMaintenanceWindow"
            case shardCapacity = "shardCapacity"
            case shardCount = "shardCount"
            case shardInstanceCount = "shardInstanceCount"
            case shards = "shards"
            case status = "status"
            case subnetIds = "subnetIds"
            case vpcSecurityGroupIds = "vpcSecurityGroupIds"
        }
    }

    public struct ClusterInList: AWSDecodableShape {
        /// The ARN identifier of the elastic cluster.
        public let clusterArn: String
        /// The name of the elastic cluster.
        public let clusterName: String
        /// The status of the elastic cluster.
        public let status: Status

        @inlinable
        public init(clusterArn: String, clusterName: String, status: Status) {
            self.clusterArn = clusterArn
            self.clusterName = clusterName
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case clusterArn = "clusterArn"
            case clusterName = "clusterName"
            case status = "status"
        }
    }

    public struct ClusterSnapshot: AWSDecodableShape {
        /// The name of the elastic cluster administrator.
        public let adminUserName: String
        /// The ARN identifier of the elastic cluster.
        public let clusterArn: String
        /// The time when the elastic cluster was created in Universal Coordinated Time (UTC).
        public let clusterCreationTime: String
        /// The KMS key identifier is the Amazon Resource Name (ARN) for the KMS encryption key.  If you are creating a cluster using the same Amazon account that owns this KMS encryption key, you can use the KMS key alias instead of the ARN as the KMS encryption key. If an encryption key is not specified here, Amazon DocumentDB uses the default encryption key that KMS creates for your account.  Your account has a different default encryption key for each Amazon Region.
        public let kmsKeyId: String
        /// The ARN identifier of the elastic cluster snapshot.
        public let snapshotArn: String
        /// The time when the elastic cluster snapshot was created in Universal Coordinated Time (UTC).
        public let snapshotCreationTime: String
        /// The name of the elastic cluster snapshot.
        public let snapshotName: String
        /// The type of cluster snapshots to be returned.  You can specify one of the following values:    automated - Return all cluster snapshots that Amazon DocumentDB has automatically created for your Amazon Web Services account.    manual - Return all cluster snapshots that you have manually created for your Amazon Web Services account.
        public let snapshotType: SnapshotType?
        /// The status of the elastic cluster snapshot.
        public let status: Status
        /// The Amazon EC2 subnet IDs for the elastic cluster.
        public let subnetIds: [String]
        /// A list of EC2 VPC security groups to associate with the elastic cluster.
        public let vpcSecurityGroupIds: [String]

        @inlinable
        public init(adminUserName: String, clusterArn: String, clusterCreationTime: String, kmsKeyId: String, snapshotArn: String, snapshotCreationTime: String, snapshotName: String, snapshotType: SnapshotType? = nil, status: Status, subnetIds: [String], vpcSecurityGroupIds: [String]) {
            self.adminUserName = adminUserName
            self.clusterArn = clusterArn
            self.clusterCreationTime = clusterCreationTime
            self.kmsKeyId = kmsKeyId
            self.snapshotArn = snapshotArn
            self.snapshotCreationTime = snapshotCreationTime
            self.snapshotName = snapshotName
            self.snapshotType = snapshotType
            self.status = status
            self.subnetIds = subnetIds
            self.vpcSecurityGroupIds = vpcSecurityGroupIds
        }

        private enum CodingKeys: String, CodingKey {
            case adminUserName = "adminUserName"
            case clusterArn = "clusterArn"
            case clusterCreationTime = "clusterCreationTime"
            case kmsKeyId = "kmsKeyId"
            case snapshotArn = "snapshotArn"
            case snapshotCreationTime = "snapshotCreationTime"
            case snapshotName = "snapshotName"
            case snapshotType = "snapshotType"
            case status = "status"
            case subnetIds = "subnetIds"
            case vpcSecurityGroupIds = "vpcSecurityGroupIds"
        }
    }

    public struct ClusterSnapshotInList: AWSDecodableShape {
        /// The ARN identifier of the elastic cluster.
        public let clusterArn: String
        /// The ARN identifier of the elastic cluster snapshot.
        public let snapshotArn: String
        /// The time when the elastic cluster snapshot was created in Universal Coordinated Time (UTC).
        public let snapshotCreationTime: String
        /// The name of the elastic cluster snapshot.
        public let snapshotName: String
        /// The status of the elastic cluster snapshot.
        public let status: Status

        @inlinable
        public init(clusterArn: String, snapshotArn: String, snapshotCreationTime: String, snapshotName: String, status: Status) {
            self.clusterArn = clusterArn
            self.snapshotArn = snapshotArn
            self.snapshotCreationTime = snapshotCreationTime
            self.snapshotName = snapshotName
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case clusterArn = "clusterArn"
            case snapshotArn = "snapshotArn"
            case snapshotCreationTime = "snapshotCreationTime"
            case snapshotName = "snapshotName"
            case status = "status"
        }
    }

    public struct ConflictException: AWSErrorShape {
        public let message: String
        /// The ID of the resource where there was an access conflict.
        public let resourceId: String
        /// The type of the resource where there was an access conflict.
        public let resourceType: String

        @inlinable
        public init(message: String, resourceId: String, resourceType: String) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct CopyClusterSnapshotInput: AWSEncodableShape {
        /// Set to true to copy all tags from the source cluster snapshot to the target elastic cluster snapshot.  The default is false.
        public let copyTags: Bool?
        /// The Amazon Web Services KMS key ID for an encrypted elastic cluster snapshot.  The Amazon Web Services KMS key ID is the Amazon Resource Name (ARN), Amazon Web Services KMS key identifier, or the Amazon Web Services KMS key alias for the Amazon Web Services KMS encryption key. If you copy an encrypted elastic cluster snapshot from your Amazon Web Services account, you can specify a value for KmsKeyId to encrypt the copy with a new Amazon Web ServicesS KMS encryption key.  If you don't specify a value for KmsKeyId, then the copy of the elastic cluster snapshot is encrypted with the same AWS KMS key as the source elastic cluster snapshot. To copy an encrypted elastic cluster snapshot to another Amazon Web Services region, set KmsKeyId to the Amazon Web Services KMS key ID that you want to use to encrypt the copy of the elastic cluster snapshot in the destination region.  Amazon Web Services KMS encryption keys are specific to the Amazon Web Services region that they are created in, and you can't use encryption keys from one Amazon Web Services region in another Amazon Web Services region. If you copy an unencrypted elastic cluster snapshot and specify a value for the KmsKeyId parameter, an error is returned.
        public let kmsKeyId: String?
        /// The Amazon Resource Name (ARN) identifier of the elastic cluster snapshot.
        public let snapshotArn: String
        /// The tags to be assigned to the elastic cluster snapshot.
        public let tags: [String: String]?
        /// The identifier of the new elastic cluster snapshot to create from the source cluster snapshot.  This parameter is not case sensitive. Constraints:   Must contain from 1 to 63 letters, numbers, or hyphens.   The first character must be a letter.   Cannot end with a hyphen or contain two consecutive hyphens.   Example: elastic-cluster-snapshot-5
        public let targetSnapshotName: String

        @inlinable
        public init(copyTags: Bool? = nil, kmsKeyId: String? = nil, snapshotArn: String, tags: [String: String]? = nil, targetSnapshotName: String) {
            self.copyTags = copyTags
            self.kmsKeyId = kmsKeyId
            self.snapshotArn = snapshotArn
            self.tags = tags
            self.targetSnapshotName = targetSnapshotName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.copyTags, forKey: .copyTags)
            try container.encodeIfPresent(self.kmsKeyId, forKey: .kmsKeyId)
            request.encodePath(self.snapshotArn, key: "snapshotArn")
            try container.encodeIfPresent(self.tags, forKey: .tags)
            try container.encode(self.targetSnapshotName, forKey: .targetSnapshotName)
        }

        public func validate(name: String) throws {
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case copyTags = "copyTags"
            case kmsKeyId = "kmsKeyId"
            case tags = "tags"
            case targetSnapshotName = "targetSnapshotName"
        }
    }

    public struct CopyClusterSnapshotOutput: AWSDecodableShape {
        public let snapshot: ClusterSnapshot

        @inlinable
        public init(snapshot: ClusterSnapshot) {
            self.snapshot = snapshot
        }

        private enum CodingKeys: String, CodingKey {
            case snapshot = "snapshot"
        }
    }

    public struct CreateClusterInput: AWSEncodableShape {
        /// The name of the Amazon DocumentDB elastic clusters administrator.  Constraints:   Must be from 1 to 63 letters or numbers.   The first character must be a letter.   Cannot be a reserved word.
        public let adminUserName: String
        /// The password for the Amazon DocumentDB elastic clusters administrator. The password can contain any printable ASCII characters.  Constraints:   Must contain from 8 to 100 characters.   Cannot contain a forward slash (/), double quote ("), or the "at" symbol (@).
        public let adminUserPassword: String
        /// The authentication type used to determine where to fetch the password used for accessing the elastic cluster.  Valid types are PLAIN_TEXT or SECRET_ARN.
        public let authType: Auth
        /// The number of days for which automatic snapshots are retained.
        public let backupRetentionPeriod: Int?
        /// The client token for the elastic cluster.
        public let clientToken: String?
        /// The name of the new elastic cluster. This parameter is stored as a lowercase string.  Constraints:   Must contain from 1 to 63 letters, numbers, or hyphens.   The first character must be a letter.   Cannot end with a hyphen or contain two consecutive hyphens.    Example: my-cluster
        public let clusterName: String
        /// The KMS key identifier to use to encrypt the new elastic cluster. The KMS key identifier is the Amazon Resource Name (ARN) for the KMS encryption key. If you are creating a cluster using the same Amazon account that owns this KMS encryption key, you can use the KMS key alias instead of the ARN as the KMS encryption key. If an encryption key is not specified, Amazon DocumentDB uses the default encryption key that KMS creates for your account. Your account has a different default encryption key for each Amazon Region.
        public let kmsKeyId: String?
        /// The daily time range during which automated backups are created if automated backups are enabled, as determined by the backupRetentionPeriod.
        public let preferredBackupWindow: String?
        /// The weekly time range during which system maintenance can occur, in Universal Coordinated Time (UTC).  Format: ddd:hh24:mi-ddd:hh24:mi   Default: a 30-minute window selected at random from an 8-hour block of time for each Amazon Web Services Region, occurring on a random day of the week.  Valid days: Mon, Tue, Wed, Thu, Fri, Sat, Sun  Constraints: Minimum 30-minute window.
        public let preferredMaintenanceWindow: String?
        /// The number of vCPUs assigned to each elastic cluster shard. Maximum is 64. Allowed values are 2, 4, 8, 16, 32, 64.
        public let shardCapacity: Int
        /// The number of shards assigned to the elastic cluster. Maximum is 32.
        public let shardCount: Int
        /// The number of replica instances applying to all shards in the elastic cluster.  A shardInstanceCount value of 1 means there is one writer instance, and any additional instances are replicas that can be used for reads and to improve availability.
        public let shardInstanceCount: Int?
        /// The Amazon EC2 subnet IDs for the new elastic cluster.
        public let subnetIds: [String]?
        /// The tags to be assigned to the new elastic cluster.
        public let tags: [String: String]?
        /// A list of EC2 VPC security groups to associate with the new elastic cluster.
        public let vpcSecurityGroupIds: [String]?

        @inlinable
        public init(adminUserName: String, adminUserPassword: String, authType: Auth, backupRetentionPeriod: Int? = nil, clientToken: String? = CreateClusterInput.idempotencyToken(), clusterName: String, kmsKeyId: String? = nil, preferredBackupWindow: String? = nil, preferredMaintenanceWindow: String? = nil, shardCapacity: Int, shardCount: Int, shardInstanceCount: Int? = nil, subnetIds: [String]? = nil, tags: [String: String]? = nil, vpcSecurityGroupIds: [String]? = nil) {
            self.adminUserName = adminUserName
            self.adminUserPassword = adminUserPassword
            self.authType = authType
            self.backupRetentionPeriod = backupRetentionPeriod
            self.clientToken = clientToken
            self.clusterName = clusterName
            self.kmsKeyId = kmsKeyId
            self.preferredBackupWindow = preferredBackupWindow
            self.preferredMaintenanceWindow = preferredMaintenanceWindow
            self.shardCapacity = shardCapacity
            self.shardCount = shardCount
            self.shardInstanceCount = shardInstanceCount
            self.subnetIds = subnetIds
            self.tags = tags
            self.vpcSecurityGroupIds = vpcSecurityGroupIds
        }

        public func validate(name: String) throws {
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case adminUserName = "adminUserName"
            case adminUserPassword = "adminUserPassword"
            case authType = "authType"
            case backupRetentionPeriod = "backupRetentionPeriod"
            case clientToken = "clientToken"
            case clusterName = "clusterName"
            case kmsKeyId = "kmsKeyId"
            case preferredBackupWindow = "preferredBackupWindow"
            case preferredMaintenanceWindow = "preferredMaintenanceWindow"
            case shardCapacity = "shardCapacity"
            case shardCount = "shardCount"
            case shardInstanceCount = "shardInstanceCount"
            case subnetIds = "subnetIds"
            case tags = "tags"
            case vpcSecurityGroupIds = "vpcSecurityGroupIds"
        }
    }

    public struct CreateClusterOutput: AWSDecodableShape {
        /// The new elastic cluster that has been created.
        public let cluster: Cluster

        @inlinable
        public init(cluster: Cluster) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "cluster"
        }
    }

    public struct CreateClusterSnapshotInput: AWSEncodableShape {
        /// The ARN identifier of the elastic cluster of which you want to create a snapshot.
        public let clusterArn: String
        /// The name of the new elastic cluster snapshot.
        public let snapshotName: String
        /// The tags to be assigned to the new elastic cluster snapshot.
        public let tags: [String: String]?

        @inlinable
        public init(clusterArn: String, snapshotName: String, tags: [String: String]? = nil) {
            self.clusterArn = clusterArn
            self.snapshotName = snapshotName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case clusterArn = "clusterArn"
            case snapshotName = "snapshotName"
            case tags = "tags"
        }
    }

    public struct CreateClusterSnapshotOutput: AWSDecodableShape {
        /// Returns information about the new elastic cluster snapshot.
        public let snapshot: ClusterSnapshot

        @inlinable
        public init(snapshot: ClusterSnapshot) {
            self.snapshot = snapshot
        }

        private enum CodingKeys: String, CodingKey {
            case snapshot = "snapshot"
        }
    }

    public struct DeleteClusterInput: AWSEncodableShape {
        /// The ARN identifier of the elastic cluster that is to be deleted.
        public let clusterArn: String

        @inlinable
        public init(clusterArn: String) {
            self.clusterArn = clusterArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.clusterArn, key: "clusterArn")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteClusterOutput: AWSDecodableShape {
        /// Returns information about the newly deleted elastic cluster.
        public let cluster: Cluster

        @inlinable
        public init(cluster: Cluster) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "cluster"
        }
    }

    public struct DeleteClusterSnapshotInput: AWSEncodableShape {
        /// The ARN identifier of the elastic cluster snapshot that is to be deleted.
        public let snapshotArn: String

        @inlinable
        public init(snapshotArn: String) {
            self.snapshotArn = snapshotArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.snapshotArn, key: "snapshotArn")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteClusterSnapshotOutput: AWSDecodableShape {
        /// Returns information about the newly deleted elastic cluster snapshot.
        public let snapshot: ClusterSnapshot

        @inlinable
        public init(snapshot: ClusterSnapshot) {
            self.snapshot = snapshot
        }

        private enum CodingKeys: String, CodingKey {
            case snapshot = "snapshot"
        }
    }

    public struct GetClusterInput: AWSEncodableShape {
        /// The ARN identifier of the elastic cluster.
        public let clusterArn: String

        @inlinable
        public init(clusterArn: String) {
            self.clusterArn = clusterArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.clusterArn, key: "clusterArn")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetClusterOutput: AWSDecodableShape {
        /// Returns information about a specific elastic cluster.
        public let cluster: Cluster

        @inlinable
        public init(cluster: Cluster) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "cluster"
        }
    }

    public struct GetClusterSnapshotInput: AWSEncodableShape {
        /// The ARN identifier of the elastic cluster snapshot.
        public let snapshotArn: String

        @inlinable
        public init(snapshotArn: String) {
            self.snapshotArn = snapshotArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.snapshotArn, key: "snapshotArn")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetClusterSnapshotOutput: AWSDecodableShape {
        /// Returns information about a specific elastic cluster snapshot.
        public let snapshot: ClusterSnapshot

        @inlinable
        public init(snapshot: ClusterSnapshot) {
            self.snapshot = snapshot
        }

        private enum CodingKeys: String, CodingKey {
            case snapshot = "snapshot"
        }
    }

    public struct GetPendingMaintenanceActionInput: AWSEncodableShape {
        /// Retrieves pending maintenance actions for a specific Amazon Resource Name (ARN).
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetPendingMaintenanceActionOutput: AWSDecodableShape {
        /// Provides information about a pending maintenance action for a resource.
        public let resourcePendingMaintenanceAction: ResourcePendingMaintenanceAction

        @inlinable
        public init(resourcePendingMaintenanceAction: ResourcePendingMaintenanceAction) {
            self.resourcePendingMaintenanceAction = resourcePendingMaintenanceAction
        }

        private enum CodingKeys: String, CodingKey {
            case resourcePendingMaintenanceAction = "resourcePendingMaintenanceAction"
        }
    }

    public struct ListClusterSnapshotsInput: AWSEncodableShape {
        /// The ARN identifier of the elastic cluster.
        public let clusterArn: String?
        /// The maximum number of elastic cluster snapshot results to receive in the response.
        public let maxResults: Int?
        /// A pagination token provided by a previous request.  If this parameter is specified, the response includes only records beyond this token, up to the value specified by max-results. If there is no more data in the responce, the nextToken will not be returned.
        public let nextToken: String?
        /// The type of cluster snapshots to be returned. You can specify one of the following values:    automated - Return all cluster snapshots that Amazon DocumentDB has automatically created for your Amazon Web Services account.    manual - Return all cluster snapshots that you have manually created for your Amazon Web Services account.
        public let snapshotType: String?

        @inlinable
        public init(clusterArn: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, snapshotType: String? = nil) {
            self.clusterArn = clusterArn
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.snapshotType = snapshotType
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.clusterArn, key: "clusterArn")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.snapshotType, key: "snapshotType")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListClusterSnapshotsOutput: AWSDecodableShape {
        /// A pagination token provided by a previous request.  If this parameter is specified, the response includes only records beyond this token, up to the value specified by max-results. If there is no more data in the responce, the nextToken will not be returned.
        public let nextToken: String?
        /// A list of snapshots for a specified elastic cluster.
        public let snapshots: [ClusterSnapshotInList]?

        @inlinable
        public init(nextToken: String? = nil, snapshots: [ClusterSnapshotInList]? = nil) {
            self.nextToken = nextToken
            self.snapshots = snapshots
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case snapshots = "snapshots"
        }
    }

    public struct ListClustersInput: AWSEncodableShape {
        /// The maximum number of elastic cluster snapshot results to receive in the response.
        public let maxResults: Int?
        /// A pagination token provided by a previous request.  If this parameter is specified, the response includes only records beyond this token, up to the value specified by max-results. If there is no more data in the responce, the nextToken will not be returned.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListClustersOutput: AWSDecodableShape {
        /// A list of Amazon DocumentDB elastic clusters.
        public let clusters: [ClusterInList]?
        /// A pagination token provided by a previous request.  If this parameter is specified, the response includes only records beyond this token, up to the value specified by max-results. If there is no more data in the responce, the nextToken will not be returned.
        public let nextToken: String?

        @inlinable
        public init(clusters: [ClusterInList]? = nil, nextToken: String? = nil) {
            self.clusters = clusters
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case clusters = "clusters"
            case nextToken = "nextToken"
        }
    }

    public struct ListPendingMaintenanceActionsInput: AWSEncodableShape {
        /// The maximum number of results to include in the response.  If more records exist than the specified maxResults value, a pagination token (marker) is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional pagination token provided by a previous request. If this parameter is specified, the response includes only records beyond the marker, up to the value specified by maxResults.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListPendingMaintenanceActionsOutput: AWSDecodableShape {
        /// An optional pagination token provided by a previous request. If this parameter is displayed, the responses will include only records beyond the marker, up to the value specified by maxResults.
        public let nextToken: String?
        /// Provides information about a pending maintenance action for a resource.
        public let resourcePendingMaintenanceActions: [ResourcePendingMaintenanceAction]

        @inlinable
        public init(nextToken: String? = nil, resourcePendingMaintenanceActions: [ResourcePendingMaintenanceAction]) {
            self.nextToken = nextToken
            self.resourcePendingMaintenanceActions = resourcePendingMaintenanceActions
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case resourcePendingMaintenanceActions = "resourcePendingMaintenanceActions"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// The ARN identifier of the elastic cluster resource.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// The list of tags for the specified elastic cluster resource.
        public let tags: [String: String]?

        @inlinable
        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct PendingMaintenanceActionDetails: AWSDecodableShape {
        /// Displays the specific action of a pending maintenance action.
        public let action: String
        /// Displays the date of the maintenance window when the action is applied.  The maintenance action is applied to the resource during its first maintenance window after this date.  If this date is specified, any NEXT_MAINTENANCE optInType requests are ignored.
        public let autoAppliedAfterDate: String?
        /// Displays the effective date when the pending maintenance action is applied to the resource.
        public let currentApplyDate: String?
        /// Displays a description providing more detail about the maintenance action.
        public let description: String?
        /// Displays the date when the maintenance action is automatically applied.  The maintenance action is applied to the resource on this date regardless of the maintenance window for the resource.  If this date is specified, any IMMEDIATE optInType requests are ignored.
        public let forcedApplyDate: String?
        /// Displays the type of optInType request that has been received for the resource.
        public let optInStatus: String?

        @inlinable
        public init(action: String, autoAppliedAfterDate: String? = nil, currentApplyDate: String? = nil, description: String? = nil, forcedApplyDate: String? = nil, optInStatus: String? = nil) {
            self.action = action
            self.autoAppliedAfterDate = autoAppliedAfterDate
            self.currentApplyDate = currentApplyDate
            self.description = description
            self.forcedApplyDate = forcedApplyDate
            self.optInStatus = optInStatus
        }

        private enum CodingKeys: String, CodingKey {
            case action = "action"
            case autoAppliedAfterDate = "autoAppliedAfterDate"
            case currentApplyDate = "currentApplyDate"
            case description = "description"
            case forcedApplyDate = "forcedApplyDate"
            case optInStatus = "optInStatus"
        }
    }

    public struct ResourceNotFoundException: AWSErrorShape {
        /// An error message describing the failure.
        public let message: String
        /// The ID of the resource that could not be located.
        public let resourceId: String
        /// The type of the resource that could not be found.
        public let resourceType: String

        @inlinable
        public init(message: String, resourceId: String, resourceType: String) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct ResourcePendingMaintenanceAction: AWSDecodableShape {
        /// Provides information about a pending maintenance action for a resource.
        public let pendingMaintenanceActionDetails: [PendingMaintenanceActionDetails]?
        /// The Amazon DocumentDB Amazon Resource Name (ARN) of the resource to which the pending maintenance action applies.
        public let resourceArn: String?

        @inlinable
        public init(pendingMaintenanceActionDetails: [PendingMaintenanceActionDetails]? = nil, resourceArn: String? = nil) {
            self.pendingMaintenanceActionDetails = pendingMaintenanceActionDetails
            self.resourceArn = resourceArn
        }

        private enum CodingKeys: String, CodingKey {
            case pendingMaintenanceActionDetails = "pendingMaintenanceActionDetails"
            case resourceArn = "resourceArn"
        }
    }

    public struct RestoreClusterFromSnapshotInput: AWSEncodableShape {
        /// The name of the elastic cluster.
        public let clusterName: String
        /// The KMS key identifier to use to encrypt the new Amazon DocumentDB elastic clusters cluster. The KMS key identifier is the Amazon Resource Name (ARN) for the KMS encryption key. If you are creating a cluster using the same Amazon account that owns this KMS encryption key, you can use the KMS key alias instead of the ARN as the KMS encryption key. If an encryption key is not specified here, Amazon DocumentDB uses the default encryption key that KMS creates for your account. Your account has a different default encryption key for each Amazon Region.
        public let kmsKeyId: String?
        /// The capacity of each shard in the new restored elastic cluster.
        public let shardCapacity: Int?
        /// The number of replica instances applying to all shards in the elastic cluster.  A shardInstanceCount value of 1 means there is one writer instance, and any additional instances are replicas that can be used for reads and to improve availability.
        public let shardInstanceCount: Int?
        /// The ARN identifier of the elastic cluster snapshot.
        public let snapshotArn: String
        /// The Amazon EC2 subnet IDs for the elastic cluster.
        public let subnetIds: [String]?
        /// A list of the tag names to be assigned to the restored elastic cluster, in the form of an array of key-value pairs in which the key is the tag name and the value is the key value.
        public let tags: [String: String]?
        /// A list of EC2 VPC security groups to associate with the elastic cluster.
        public let vpcSecurityGroupIds: [String]?

        @inlinable
        public init(clusterName: String, kmsKeyId: String? = nil, shardCapacity: Int? = nil, shardInstanceCount: Int? = nil, snapshotArn: String, subnetIds: [String]? = nil, tags: [String: String]? = nil, vpcSecurityGroupIds: [String]? = nil) {
            self.clusterName = clusterName
            self.kmsKeyId = kmsKeyId
            self.shardCapacity = shardCapacity
            self.shardInstanceCount = shardInstanceCount
            self.snapshotArn = snapshotArn
            self.subnetIds = subnetIds
            self.tags = tags
            self.vpcSecurityGroupIds = vpcSecurityGroupIds
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.clusterName, forKey: .clusterName)
            try container.encodeIfPresent(self.kmsKeyId, forKey: .kmsKeyId)
            try container.encodeIfPresent(self.shardCapacity, forKey: .shardCapacity)
            try container.encodeIfPresent(self.shardInstanceCount, forKey: .shardInstanceCount)
            request.encodePath(self.snapshotArn, key: "snapshotArn")
            try container.encodeIfPresent(self.subnetIds, forKey: .subnetIds)
            try container.encodeIfPresent(self.tags, forKey: .tags)
            try container.encodeIfPresent(self.vpcSecurityGroupIds, forKey: .vpcSecurityGroupIds)
        }

        public func validate(name: String) throws {
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "clusterName"
            case kmsKeyId = "kmsKeyId"
            case shardCapacity = "shardCapacity"
            case shardInstanceCount = "shardInstanceCount"
            case subnetIds = "subnetIds"
            case tags = "tags"
            case vpcSecurityGroupIds = "vpcSecurityGroupIds"
        }
    }

    public struct RestoreClusterFromSnapshotOutput: AWSDecodableShape {
        /// Returns information about a the restored elastic cluster.
        public let cluster: Cluster

        @inlinable
        public init(cluster: Cluster) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "cluster"
        }
    }

    public struct Shard: AWSDecodableShape {
        /// The time when the shard was created in Universal Coordinated Time (UTC).
        public let createTime: String
        /// The ID of the shard.
        public let shardId: String
        /// The current status of the shard.
        public let status: Status

        @inlinable
        public init(createTime: String, shardId: String, status: Status) {
            self.createTime = createTime
            self.shardId = shardId
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case createTime = "createTime"
            case shardId = "shardId"
            case status = "status"
        }
    }

    public struct StartClusterInput: AWSEncodableShape {
        /// The ARN identifier of the elastic cluster.
        public let clusterArn: String

        @inlinable
        public init(clusterArn: String) {
            self.clusterArn = clusterArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.clusterArn, key: "clusterArn")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct StartClusterOutput: AWSDecodableShape {
        public let cluster: Cluster

        @inlinable
        public init(cluster: Cluster) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "cluster"
        }
    }

    public struct StopClusterInput: AWSEncodableShape {
        /// The ARN identifier of the elastic cluster.
        public let clusterArn: String

        @inlinable
        public init(clusterArn: String) {
            self.clusterArn = clusterArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.clusterArn, key: "clusterArn")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct StopClusterOutput: AWSDecodableShape {
        public let cluster: Cluster

        @inlinable
        public init(cluster: Cluster) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "cluster"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The ARN identifier of the elastic cluster resource.
        public let resourceArn: String
        /// The tags that are assigned to the elastic cluster resource.
        public let tags: [String: String]

        @inlinable
        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            try container.encode(self.tags, forKey: .tags)
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct ThrottlingException: AWSErrorShape {
        public let message: String
        /// The number of seconds to wait before retrying the operation.
        public let retryAfterSeconds: Int?

        @inlinable
        public init(message: String, retryAfterSeconds: Int? = nil) {
            self.message = message
            self.retryAfterSeconds = retryAfterSeconds
        }

        public init(from decoder: Decoder) throws {
            let response = decoder.userInfo[.awsResponse]! as! ResponseDecodingContainer
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.message = try container.decode(String.self, forKey: .message)
            self.retryAfterSeconds = try response.decodeHeaderIfPresent(Int.self, key: "Retry-After")
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The ARN identifier of the elastic cluster resource.
        public let resourceArn: String
        /// The tag keys to be removed from the elastic cluster resource.
        public let tagKeys: [String]

        @inlinable
        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            request.encodeQuery(self.tagKeys, key: "tagKeys")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateClusterInput: AWSEncodableShape {
        /// The password associated with the elastic cluster administrator.  This password can contain any printable ASCII character except forward slash (/), double quote ("), or the "at" symbol (@).  Constraints: Must contain from 8 to 100 characters.
        public let adminUserPassword: String?
        /// The authentication type used to determine where to fetch the password used for accessing the elastic cluster.  Valid types are PLAIN_TEXT or SECRET_ARN.
        public let authType: Auth?
        /// The number of days for which automatic snapshots are retained.
        public let backupRetentionPeriod: Int?
        /// The client token for the elastic cluster.
        public let clientToken: String?
        /// The ARN identifier of the elastic cluster.
        public let clusterArn: String
        /// The daily time range during which automated backups are created if automated backups are enabled, as determined by the backupRetentionPeriod.
        public let preferredBackupWindow: String?
        /// The weekly time range during which system maintenance can occur, in Universal Coordinated Time (UTC).  Format: ddd:hh24:mi-ddd:hh24:mi   Default: a 30-minute window selected at random from an 8-hour block of time for each Amazon Web Services Region, occurring on a random day of the week.  Valid days: Mon, Tue, Wed, Thu, Fri, Sat, Sun  Constraints: Minimum 30-minute window.
        public let preferredMaintenanceWindow: String?
        /// The number of vCPUs assigned to each elastic cluster shard.  Maximum is 64. Allowed values are 2, 4, 8, 16, 32, 64.
        public let shardCapacity: Int?
        /// The number of shards assigned to the elastic cluster. Maximum is 32.
        public let shardCount: Int?
        /// The number of replica instances applying to all shards in the elastic cluster.  A shardInstanceCount value of 1 means there is one writer instance, and any additional instances are replicas that can be used for reads and to improve availability.
        public let shardInstanceCount: Int?
        /// The Amazon EC2 subnet IDs for the elastic cluster.
        public let subnetIds: [String]?
        /// A list of EC2 VPC security groups to associate with the elastic cluster.
        public let vpcSecurityGroupIds: [String]?

        @inlinable
        public init(adminUserPassword: String? = nil, authType: Auth? = nil, backupRetentionPeriod: Int? = nil, clientToken: String? = UpdateClusterInput.idempotencyToken(), clusterArn: String, preferredBackupWindow: String? = nil, preferredMaintenanceWindow: String? = nil, shardCapacity: Int? = nil, shardCount: Int? = nil, shardInstanceCount: Int? = nil, subnetIds: [String]? = nil, vpcSecurityGroupIds: [String]? = nil) {
            self.adminUserPassword = adminUserPassword
            self.authType = authType
            self.backupRetentionPeriod = backupRetentionPeriod
            self.clientToken = clientToken
            self.clusterArn = clusterArn
            self.preferredBackupWindow = preferredBackupWindow
            self.preferredMaintenanceWindow = preferredMaintenanceWindow
            self.shardCapacity = shardCapacity
            self.shardCount = shardCount
            self.shardInstanceCount = shardInstanceCount
            self.subnetIds = subnetIds
            self.vpcSecurityGroupIds = vpcSecurityGroupIds
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.adminUserPassword, forKey: .adminUserPassword)
            try container.encodeIfPresent(self.authType, forKey: .authType)
            try container.encodeIfPresent(self.backupRetentionPeriod, forKey: .backupRetentionPeriod)
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            request.encodePath(self.clusterArn, key: "clusterArn")
            try container.encodeIfPresent(self.preferredBackupWindow, forKey: .preferredBackupWindow)
            try container.encodeIfPresent(self.preferredMaintenanceWindow, forKey: .preferredMaintenanceWindow)
            try container.encodeIfPresent(self.shardCapacity, forKey: .shardCapacity)
            try container.encodeIfPresent(self.shardCount, forKey: .shardCount)
            try container.encodeIfPresent(self.shardInstanceCount, forKey: .shardInstanceCount)
            try container.encodeIfPresent(self.subnetIds, forKey: .subnetIds)
            try container.encodeIfPresent(self.vpcSecurityGroupIds, forKey: .vpcSecurityGroupIds)
        }

        private enum CodingKeys: String, CodingKey {
            case adminUserPassword = "adminUserPassword"
            case authType = "authType"
            case backupRetentionPeriod = "backupRetentionPeriod"
            case clientToken = "clientToken"
            case preferredBackupWindow = "preferredBackupWindow"
            case preferredMaintenanceWindow = "preferredMaintenanceWindow"
            case shardCapacity = "shardCapacity"
            case shardCount = "shardCount"
            case shardInstanceCount = "shardInstanceCount"
            case subnetIds = "subnetIds"
            case vpcSecurityGroupIds = "vpcSecurityGroupIds"
        }
    }

    public struct UpdateClusterOutput: AWSDecodableShape {
        /// Returns information about the updated elastic cluster.
        public let cluster: Cluster

        @inlinable
        public init(cluster: Cluster) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "cluster"
        }
    }

    public struct ValidationException: AWSErrorShape {
        /// A list of the fields in which the validation exception occurred.
        public let fieldList: [ValidationExceptionField]?
        /// An error message describing the validation exception.
        public let message: String
        /// The reason why the validation exception occurred (one of unknownOperation, cannotParse, fieldValidationFailed, or other).
        public let reason: ValidationExceptionReason

        @inlinable
        public init(fieldList: [ValidationExceptionField]? = nil, message: String, reason: ValidationExceptionReason) {
            self.fieldList = fieldList
            self.message = message
            self.reason = reason
        }

        private enum CodingKeys: String, CodingKey {
            case fieldList = "fieldList"
            case message = "message"
            case reason = "reason"
        }
    }

    public struct ValidationExceptionField: AWSDecodableShape {
        /// An error message describing the validation exception in this field.
        public let message: String
        /// The name of the field where the validation exception occurred.
        public let name: String

        @inlinable
        public init(message: String, name: String) {
            self.message = message
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case name = "name"
        }
    }
}

// MARK: - Errors

/// Error enum for DocDBElastic
public struct DocDBElasticErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize DocDBElastic
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// An exception that occurs when there are not sufficient permissions to perform an action.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// There was an access conflict.
    public static var conflictException: Self { .init(.conflictException) }
    /// There was an internal server error.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// The specified resource could not be located.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// The service quota for the action was exceeded.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// ThrottlingException will be thrown when request was denied due to request throttling.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// A structure defining a validation exception.
    public static var validationException: Self { .init(.validationException) }
}

extension DocDBElasticErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "ConflictException": DocDBElastic.ConflictException.self,
        "ResourceNotFoundException": DocDBElastic.ResourceNotFoundException.self,
        "ThrottlingException": DocDBElastic.ThrottlingException.self,
        "ValidationException": DocDBElastic.ValidationException.self
    ]
}

extension DocDBElasticErrorType: Equatable {
    public static func == (lhs: DocDBElasticErrorType, rhs: DocDBElasticErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension DocDBElasticErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
